#ifndef AREADETECTIONMODEL_H
#define AREADETECTIONMODEL_H

#include <QtCore/QVector>

#include "imagemodel.h"
#include "backgroundtask.h"

class AreaDetectionModel;

#define GRAYSCALE_COLOR_RANGE 256 // TODO
#define DEFAULT_THRESHOLD_VALUE 0

/**
 * Background task for computing histogram
 */
class ComputeHistogramTask : public BackgroundTask {

public:

    /**
     * Constructor
     * @param model model
     */
    ComputeHistogramTask(AreaDetectionModel& model, QObject *parent=0);

protected:

    /**
     * Background task method
     */
    virtual void doRun();

    /**
     * Background task cancel method
     */
    virtual void doCancel();

private:

    /**
     * Model
     */
    AreaDetectionModel& _model;

};

/**
 * Background task for area detection
 */
class AreaDetectionTask : public BackgroundTask {

public:

    /**
     * Constructor
     * @param model model
     */
    AreaDetectionTask(AreaDetectionModel& model, QObject *parent=0);

protected:

    /**
     * Background task method
     */
    virtual void doRun();

    /**
     * Background task cancel method
     */
    virtual void doCancel();

private:

    /**
     * Model
     */
    AreaDetectionModel& _model;

};

/**
 * Model for area detection
 */
class AreaDetectionModel : public ImageModel
{
Q_OBJECT

public:

    /**
     * Images ID
     */
    enum ImageID {
        ESourceImage = 0,               // Source image
        EHistogramImage,                // Histogram image
        EHistogramImageWithThreshold,   // Histogram image with threshold
        EDetectedAreasImage,            // Detected areas image
        ELastImage
    };

    /**
     * Constructor     
     */
    explicit AreaDetectionModel(QObject *parent = 0);

    /**
     * Gets image
     */
    GrayscaleImage sourceImage();

    /**
     * Computes histogram
     * @return compute histogram task
     */
    ComputeHistogramTask* computeHistogram();

    /**
     * Sets histogram data
     */
    void setHistogramData(const QVector<int> &data);

    /**
     * Sets histogram image
     * @param image histogram image
     */
    void setHistogramImage(const ColorImage &image);

    /**
     * Gets histogram image
     * @return histogram image
     */
    ColorImage histogramImage();

    /**
     * Updates histogram image
     */
    void updateHistogram();

    /**
     * Detects areas in image
     * @retun detect area task
     */
    AreaDetectionTask* detectAreas();

    /**
     * Sets detected areas image
     * @param image detected areas image
     */
    void setDetectedAreasImage(const BinaryImage &image);

    /**
     * Return binary image representation of detected areas
     * @return binary image representation
     */
    BinaryImage detectedAreasImage();

    /**
     * Computes threshold value
     */
    void computeThresholdValue();

    /**
     * Threshold value
     * @return threshold value
     */
    int thresholdValue() const;

signals:

    /**
     * Emited whenever threshold value changed
     */
    void thresholdValueChanged(int);

    /**
     * Emited when areas are detected
     * @param image binary image with detected areas
     */
    void areasDetected(const BinaryImage &image);

public slots:

    /**
     * Sets image
     * @param image image for area detection
     */
    void setSourceImage(const GrayscaleImage &image);

    /**
     * Set threshold value
     * @param value threshold value;
     */
    void setThresholdValue(int value);

private:

    /**
     * Histogram data
     */
    QVector<int> _histogramData;

    /**
     * Threshold value
     */
    Grayscale _thresholdValue;

};

#endif // AREADETECTIONMODEL_H
